package com.easylinkin.linkappapi.security.config;

import com.easylinkin.bases.redis.util.RedisUtil;
import com.easylinkin.linkappapi.common.exceptions.BusinessException;
import com.easylinkin.linkappapi.security.entity.LinkappUser;
import com.easylinkin.linkappapi.security.service.LinkappUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.util.ObjectUtils;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;


public class LinkappUsernamePasswordAuthenticationFilter extends AbstractAuthenticationProcessingFilter {
	public static final String SPRING_SECURITY_FORM_USERNAME_KEY = "username";
	public static final String SPRING_SECURITY_FORM_PASSWORD_KEY = "password";

	private String usernameParameter = SPRING_SECURITY_FORM_USERNAME_KEY;
	private String passwordParameter = SPRING_SECURITY_FORM_PASSWORD_KEY;
	
	private String tokenParameter = "ssoToken";
	@Autowired
	private RedisUtil redisUtil;
	@Autowired
	private LinkappUserService linkappUserService;
	private boolean postOnly = true;
	public LinkappUsernamePasswordAuthenticationFilter() {
        super(new AntPathRequestMatcher("/ssoLogin", "GET"));
    }

	@Override
	public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
			throws AuthenticationException {
		if (postOnly && !"GET".equals(request.getMethod())) {
			throw new AuthenticationServiceException("Authentication method not supported: " + request.getMethod());
		}
		
		String token = obtainToken(request);
		String username = null;
		String password = null;
		if(token != null) {
			Object obj  = redisUtil.get(token);
			if (obj != null) {
				LinkappUser user = (LinkappUser) obj;
				username = user.getUsername();
				password = user.getPassword();
			}else {
				//如果是内置的token，则直接构造用户信息6197fb4f-2f90-420c-aa9d-f520a1c2acbe,内置用户为
				if (token.equals("6197fb4f-2f90-420c-aa9d-f520a1c2acbe")){
					LinkappUser linkappUser = linkappUserService.findByUsername("admin@16171");
					username = linkappUser.getUsername();
					password = linkappUser.getPassword();
					redisUtil.set("6197fb4f-2f90-420c-aa9d-f520a1c2acbe", linkappUser, 300);
				}
			}
		}else {
			username = obtainUsername(request);
			password = obtainPassword(request);
		}
		
		try {
		} catch (Exception e) {
			logger.error(e.getMessage(), e);
		}

		if (username == null) {
			username = "";
		}

		if (password == null) {
			password = "";
		}

		username = username.trim();

		if (ObjectUtils.isEmpty(username) || ObjectUtils.isEmpty(password)) {
			throw new BusinessException("认证失败，找不到相应用户，或密码有误，请检查token是否过期");
		}
			
		UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(username, password);

		// Allow subclasses to set the "details" property
		setDetails(request, authRequest);

		Authentication result;
		try {
			result = super.getAuthenticationManager().authenticate(authRequest);
		} catch (AuthenticationException e) {
			throw new BusinessException("认证失败，请检查参数用户名或密码或token");
		}
		return result;
	}

	@Override
	public void setAuthenticationManager(AuthenticationManager authenticationManager) {
		super.setAuthenticationManager(authenticationManager);
	}

	protected String obtainPassword(HttpServletRequest request) {
		return request.getParameter(passwordParameter).replaceAll(" ", "+");
	}

	protected String obtainUsername(HttpServletRequest request) {
		return request.getParameter(usernameParameter);
	}
	
	protected String obtainToken(HttpServletRequest request) {
		return request.getParameter(tokenParameter);
	}

	protected void setDetails(HttpServletRequest request, UsernamePasswordAuthenticationToken authRequest) {
		authRequest.setDetails(authenticationDetailsSource.buildDetails(request));
	}

	public void setUsernameParameter(String usernameParameter) {
		this.usernameParameter = usernameParameter;
	}

	public void setPasswordParameter(String passwordParameter) {
		this.passwordParameter = passwordParameter;
	}

	public void setPostOnly(boolean postOnly) {
		this.postOnly = postOnly;
	}

	public final String getUsernameParameter() {
		return usernameParameter;
	}

	public final String getPasswordParameter() {
		return passwordParameter;
	}
}
